const JSONStream = require('JSONStream');

module.exports = (app, config) => class TaskApi {

  async requestJSONStreamWithoutBody(method, api, query, opts = {}) {
    const url = this.url(api, query);
    const res = await this.ctx.fetch(url, {
      method,
      ...opts,
      headers: {
        ...this.getHeaders(),
        ...opts.headers,
      }
    });
    if (res.status < 200 || res.status > 299) {
      const e = new Error(`网络错误：${res.status} ${res.statusText || 'Unknown'}`);
      e.status = res.status;
      throw e;
    }
    try {
      const codeStream = res.body.pipe(JSONStream.parse('code'));
      const messageStream = res.body.pipe(JSONStream.parse('message'));
      const dataStream = res.body.pipe(JSONStream.parse('data.*'));
      let [code, message] = await new Promise((fulfill, reject) => {
        let code = undefined;
        let message = undefined;
        codeStream.once('data', val => {
          res.body.unpipe(codeStream);
          code = val;
          if (code === 0 || code === '0' || message !== undefined) {
            dataStream.pause();
            fulfill([code, message]);
          }
        });
        messageStream.once('data', val => {
          res.body.unpipe(messageStream);
          message = val || null;
          if (code !== undefined && message !== undefined) {
            dataStream.pause();
            fulfill([code, message]);
          }
        });
        dataStream.once('data', () => {
          if (code !== undefined) {
            fulfill([code, message]);
          } else {
            reject(new Error('Bad Response: No code before data'));
          }
        });
        dataStream.once('end', () => {
          if (code !== undefined) {
            fulfill([code, message]);
          } else {
            reject(new Error('Bad Response: No code before data'));
          }
        });
      });
      return checkResponse({
        code, message, data: dataStream
      });
    } catch (e) {
      res.body.destroy();
      throw e;
    }
  }

}

function checkResponse(data){
  console.log('task checkResponse data:',data)
  if (Number(data.code) !== 0) {
    const e = new Error(data.message || '未知错误');
    e.code = data.code;
    e.data = data.data;
    throw e;
  }
  return data.data;
}
